package io.renren.midplat.fuseclick.network;
import java.util.Date;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.bcel.internal.generic.PUSH;
import io.renren.common.main.MailService;
import io.renren.common.utils.CharUtils;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.HttpUtils;
import io.renren.midplat.fuseclick.model.OfferCapDTO;
import io.renren.midplat.fuseclick.model.OfferGeoDTO;
import io.renren.midplat.fuseclick.model.ResultDTO;
import io.renren.modules.advertiser.entity.AdvertiserEntity;
import io.renren.modules.log.entity.PushLogEntity;
import io.renren.modules.log.service.PushLogService;
import io.renren.modules.offer.entity.OfferEntity;
import io.renren.modules.offer.entity.OfferPlatformEntity;
import io.renren.modules.offer.service.OfferService;
import io.renren.modules.util.service.SysSwitchService;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * batchGetOffersByOfferslook为spring bean的名称
 *
 * @Description /aff/v1/batches/offers
 * @Author haijun.zhang@luckincoffee.com
 * @Date 2018-08-07 9:45
 */
@Service("pushOffersByFuseClickService")
public class PushOffersByFuseClickServiceImpl {

    /**
     * 日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(PushOffersByFuseClickServiceImpl.class);
    @Autowired
    private OfferService offerService;
    @Value("${fuseclick.apiDomain}")
    private String apiDomain;
    @Value("${fuseclick.setOfferURI}")
    private String setOfferURI;
    @Value("${fuseclick.key}")
    private String key;

    @Value("${fuseclick.payoutPCT}")
    private String payoutPCT;

    private String batchNo;
    @Autowired
    private MailService mailService;
    @Autowired
    private SysSwitchService sysSwitchService;
    @Autowired
    private PushLogService pushLogService;

    /**
     * URL 转码
     *
     * @return String
     * @author lifq
     * @date 2015-3-17 下午04:10:28
     */
    public static String getURLEncoderString(String str) {
        String result = "";
        if (null == str) {
            return "";
        }
        try {
            result = java.net.URLEncoder.encode(str, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    public void service(AdvertiserEntity advertiser) {
        try {
            LOGGER.info("FuseClick 推送数据开始");
            Map<String, Object> queryParams = new LinkedHashMap<>();
            queryParams.put("push_flag", 0);
            queryParams.put("ssp_channel_id", advertiser.getSspChannelId());
            List<OfferEntity> offerEntityList = offerService.selectByMap(queryParams);

            LOGGER.info("需要推送的数据量:" + offerEntityList.size());
            for (OfferEntity offerEntity : offerEntityList) {
                LOGGER.debug("offerEntity:" + offerEntity.toString());
                pushToFuseClick(offerEntity,advertiser);
            }
        } catch (Exception e) {
            LOGGER.error("pushOffersByFuseClickService ERROR");
            LOGGER.error(e.getMessage());
            e.printStackTrace();
        }
        LOGGER.info("pushOffersByFuseClickService end");
    }

    public void pushToFuseClick(OfferEntity offerEntity,AdvertiserEntity advertiser) {
        PushLogEntity pushLogEntity = new PushLogEntity();
        pushLogEntity.setBatchNo(Thread.currentThread().getName());

        pushLogEntity.setCreateDate(new Date());
        try {

            Map<String, String> header = new LinkedHashMap();
            header.put("Content-type", "application/x-www-form-urlencoded");

            Map<String, String> params = new LinkedHashMap();

            //如果数据库中没有下游offerId，则是新增操作。不对ID进行设置 如果有，则是更新操作
            if (offerEntity.getSspOfferId() != null && offerEntity.getSspOfferId() != 0) {
                params.put("id", offerEntity.getSspOfferId() + "");
            }
            params.put("advertiser_id", advertiser.getSspChannelId()+"");
            params.put("name", offerEntity.getName());

            //Active/Pending/Paused/Archived
            //TODO params.put("status",offerEntity.getPushStatus());
            if (offerEntity.getPushStatus().equals("Active")) {
                if(advertiser.getStatus()!=null && advertiser.getStatus().equals("Active")){
                    params.put("status", "Active");
                }else {
                    params.put("status", "Pending");
                }

            } else if (offerEntity.getPushStatus().equals("Paused")) {
                params.put("status", "Paused");
            }

            if(offerEntity.getMidStatus()!=null){
                LOGGER.error("设置为中间状态status："+offerEntity.getMidStatus());
                params.put("status", offerEntity.getMidStatus());
            }


            params.put("expire_date", DateUtils.toSlashDate(offerEntity.getEndDate()));

            //Desktop/Mobile/Tablet
            params.put("type", "Mobile");
            params.put("conversion_point", "Download and Install");
            params.put("preview_url", CharUtils.toEncodeExistCommon(offerEntity.getPreviewUrl()));

            //TODO 需要可配置
            params.put("url", offerEntity.getTrackingLink() + advertiser.getTrackingUrl());

            //TODO 需要业主决定 Public/Need Approval/Private
            params.put("access_type", "Need Approval");
            //params.put("access_type",transApproval(offerEntity.getOfferApproval()));

            params.put("ssl", "0");

            //Server Postback URL/iFrame Pixel/Image Pixel
            params.put("tracking_protocol", "Server Postback URL");

            //TODO 需要转换 对比一下LIST
            params.put("currency", "1");

            //TODO 检查一下转换类型 CPA/CPC/CPS/CPI/CPA+CPS/CPL
            params.put("payout_type", offerEntity.getPricingType());

            //TODO 需要可配置payoutPCT
            params.put("payout", Float.parseFloat(offerEntity.getPayout()) * Float.parseFloat(payoutPCT) + "");
            //params.put("payout_percent","");
            params.put("revenue_type", transRevenueType(offerEntity.getPricingType()));
            params.put("revenue", offerEntity.getPayout());
            //params.put("revenue_percent","");
            params.put("need_security_token", "0");
            params.put("force_unique", "0");
            params.put("session_lifespan", "1 Week");
            params.put("hide_referrer", "0");
            //params.put("secondary_offer","");
            if(offerEntity.getDescription()!=null && offerEntity.getDescription().length()>4000){
                params.put("description", offerEntity.getDescription().substring(0,3999));
            }else{
                params.put("description", offerEntity.getDescription());
            }

            //params.put("restriction","");
            params.put("has_cap_limit", "1");
            //TODO Budget/Conversion 为空的话JSON转换一下
            params.put("cap_type", "Conversion");
            //params.put("cap_event_range","");
            //params.put("cap_overall_limit","");
            params.put("cap_interval", "Daily");
            //TODO 无则默认500  有则用上游的  做成可配置
            if(offerEntity.getOfferCap()!=null){
                OfferCapDTO offerCapDTO = JSON.parseObject(offerEntity.getOfferCap(),OfferCapDTO.class);
                if(offerCapDTO!=null && offerCapDTO.getCap_type()!=null){
                    if(offerCapDTO.getCap_type().equals("2")){
                        params.put("cap_interval_limit", offerCapDTO.getCap_conversion()+"");
                    }
                }
            }
            if(!params.containsKey("cap_interval_limit")){
                params.put("cap_interval_limit", "500");
            }

            //params.put("cap_affiliate_overall_limit","");
            //params.put("cap_affiliate_interval","");
            //params.put("cap_affiliate_interval_limit","");
            params.put("device_targeting", "1");

            //设置deviceRules 有特殊转换规则
            if (offerEntity.getOfferPlatform() != null) {
                drviceRules(offerEntity.getOfferPlatform(), params);
            }
            //params.put("device_redirect_offer_id","");
            params.put("geo_targeting", "1");
            params.put("geo_type", "1");

            //设置geo_countries 有特殊转换规则
            if (offerEntity.getOfferGeo() != null) {
                countryRules(offerEntity.getOfferGeo(), params);
            }

            params.put("geo_enforce", "1");
            //params.put("geo_redirect_type","");
            //params.put("geo_redirect_target_id","");
            params.put("app_id", getAppId(offerEntity.getPreviewUrl()));
            //params.put("categories","");

            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            if(params!=null){
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
            }
            pushLogEntity.setPushData(nvps.toString());

            String response = "{\"httpStatus\":204,\"errorCode\":0,\"errorMessage\":\"\",\"message\":\"ERROR!\"}";
            if(sysSwitchService.getSwitch("PULL_FLAG")){
                response = HttpUtils.doPostForm(apiDomain + setOfferURI + key, nvps, header);
            }
            //LOGGER.info("返回结果:" + response);
            if (response != null) {
                ResultDTO resultDTO = JSON.parseObject(response, ResultDTO.class);
                pushLogEntity.setResultCode(resultDTO.getHttpStatus()+"");
                pushLogEntity.setResultMsg(response);
                if (resultDTO.getHttpStatus() == 201) {
                    offerEntity.setSspOfferId(resultDTO.getData().get(0).getId());
                    offerEntity.setPushFlag(1);
                    offerEntity.setBak("上传新建数据成功");
                    LOGGER.info("上传下游数据Create:{},Name:{}", offerEntity.getId(), offerEntity.getName());

                } else if (resultDTO.getHttpStatus() == 202) {
                    offerEntity.setPushFlag(1);
                    offerEntity.setBak("更新数据成功");
                    LOGGER.info("上传下游数据Update:{},Name:{}", offerEntity.getId(), offerEntity.getName());
                } else {
                    LOGGER.error("上传下游数据异常: id:{},HttpStatus():{},ErrorMessage:{}", offerEntity.getId(), resultDTO.getHttpStatus(), resultDTO.getMessage());
                    offerEntity.setPushFlag(2);
                    offerEntity.setBak("上传下游数据异常: ErrorCode:" + resultDTO.getHttpStatus() + "ErrorMessage:" + resultDTO.getMessage());
                    mailService.sendOffersPushErrorMail(offerEntity," ErrorCode:" + resultDTO.getHttpStatus() + "ErrorMessage:" + resultDTO.getMessage());
                }
                offerService.updateById(offerEntity);
            }
        } catch (Exception e) {
            mailService.sendOffersPushErrorMail(offerEntity," ErrorMessage:" + e.getMessage());
            pushLogEntity.setResultCode("ERROR");
            pushLogEntity.setResultMsg(e.getMessage());
            e.printStackTrace();
        } finally {
            pushLogService.insert(pushLogEntity);
        }
    }

    //CPA · CPC · CPS · CPA+CPS
    public String transRevenueType(String revenueType) {
        if (revenueType.equals("CPA")) {
            return "RPA";
        } else if (revenueType.equals("CPC")) {
            return "RPC";
        } else if (revenueType.equals("CPS")) {
            return "RPS";
        } else if (revenueType.equals("CPA+CPS")) {
            return "RPA+RPS";
        }
        return "";
    }

    public static String getAppId(String appId) {
        if (appId.startsWith("https://play.google.com")) {
            String a = appId.substring(appId.lastIndexOf("id=") + 3);
           // System.out.println(a.indexOf('&'));
            if(a.indexOf('&')>-1){
                a = a.substring(0,a.indexOf('&'));
            }
            return a;
        }
        if (appId.startsWith("https://itunes.apple.com") || appId.startsWith("http://itunes.apple.com")) {
            String a = appId.substring(appId.lastIndexOf("/id") + 1);
           // System.out.println(a.indexOf('?'));
            if(a.indexOf('?')>-1){
                a = a.substring(0,a.indexOf('?'));
            }
            return a;
        }
        if (appId.startsWith("https://cafebazaar.ir") || appId.startsWith("http://cafebazaar.ir")) {
            String a = appId.substring(appId.lastIndexOf("/app/") + 5);
            // System.out.println(a.indexOf('?'));
            if(a.indexOf('?')>-1){
                a = a.substring(0,a.indexOf('/'));
            }
            return a;
        }
        return "";
    }

    public static void main(String [] args){
        String a = "https://cafebazaar.ir/app/cab.snapp.passenger/?l=en";
        System.out.println(getAppId(a));
      //  String a = "PhonePe is a revolutionary way to make mobile payments in India. From UPI payments to recharges, money transfers to online bill payments, you can do it all on PhonePe. PhonePe is way better than Internet Banking and offers you the safest and fastest online payment experience in India. Things you can do on the PhonePe app - - Send and request money from your contacts anytime, anywhere. - Recharge prepaid Mobile for most major operators/Datacard/DTH connections across the country. - Pay postpaid Landline, Datacard and Mobile Bills for all major operators. - Pay for utilities such as electricity and gas bills. - Check your account balance, save beneficiaries and manage multiple bank accounts. - Get refunds and cashbacks to your bank account in an instant. - Split bills with your friends and settle them right away. - Shop on Flipkart, Myntra, Jabong, and other online shopping websites. PhonePe benefits - - Transact up to Rs.1 lakh per transaction, 24*7. - Get instant refunds and cashbacks from our partner merchants into your PhonePe wallet. -Check wallet balance that can be withdrawn to your bank account. Cashback cannot be withdrawn to any linked bank account and cannot be transferred to other users. Cashback can be redeemed for mobile recharges, bill payments, and used for merchant payments where PhonePe has been integrated as a payment option - Top up your wallet using your UPI enabled bank account or a debit card to make instant payments to anyone. - One-click payments using your PhonePe account at any of our merchant partner locations. - Transact in the language of your choice. English, Hindi, Tamil, Bengali, Telugu, Kannada, Malyalam, Assamese, Gujarati, and Marathi are now live. More languages coming soon! The PhonePe app works over the Unified Payments Interface (UPI) platform developed by the National Payments Corporation of India (NPCI) and is powered by YES Bank. The PhonePe UPI app is safe and secure, meets all your payment and banking needs, and is much better than Internet banking. No need to remember IFSC codes, account numbers, or other inconvenient details. Make instant bank transfers by just using a mobile number or a unique payment identity – your Virtual Payment Address (VPA). PhonePe also provides you with a digital mobile wallet for faster refunds and cashbacks from our merchant partners. You can spend your wallet balance or withdraw it into your linked bank account(s) in one quick swipe. With over 70 billers live on the PhonePe App you can do quick and easy recharges for mobiles, DTH, datacards and also pay gas, electricity, landline and other utility bills. Currently over 40 banks are UPI enabled, with more banks coming soon! Banks currently on UPI: YES Bank (our UPI sponsor), Allahabad Bank, Andhra Bank, Axis Bank, Bank of Baroda (BOB), Bank of Maharashtra, Bank of India, Canara Bank, Catholic Syrian Bank, Central Bank of India, Citibank, City Union Bank, Corporation Bank, DCB Bank, Dena Bank, Federal Bank, HDFC Bank, HSBC Bank, ICICI Bank, IDBI Bank, IDFC Bank, Indusind Bank, Indian Bank, Indian Overseas Bank, Karur Vyasa Bank, Karnataka Bank, Kotak Mahindra Bank, Laxmi Vilas Bank, Oriental Bank of Commerce, Punjab National Bank (PNB), Punjab and Sindh Bank, Ratnakar Bank (RBL), State Bank of India (SBI), South Indian Bank (SIB), Standard Chartered Bank (SCB), TJSB Sahakari Bank, UCO Bank, United Bank of India, Union Bank of India, Vijaya Bank For more details, please visit our website at https://www.phonepe.com Permissions for App and reasons: SMS - This is required to verify Phone no for registration Location - This is a requirement by NPCI for UPI transactions Contacts - We use this to for phone numbers to send money to and choose numbers to recharge. Camera - We use this to scan QR code. Storage - We use this to store scanned QR code. Accounts- This is used to prepopulate email id while signing up. Call - This is used to detect single/vs dual sim and let user choose Android Restrictions: - No bot - No fraud Hard KPI: - CR hourly max 5% - RR D1 5% Soft KPI: - RR D1 30% - RR D7 15% ??Android 4.4 + Abnormal device distribution will be considered as fraudulent | bot traffic (read as more than 20% coming from old versions both Android and iOS) e.g. there are more than 20% of iOS 9.0-9.3.5 installs. This campaign is monitored with 24metrics. ? User Flow: 1. User clicks on banner and is redirected to Google Play or the App Store. 2. User successfully downloads and installs the application. 3. User opens the application for the first time. *please note that our platform automatically blocks high CR for CPI non-incent offers if unique CR is higher than 5%. If you expect that your traffic will give higher CR due to specific reasons please contact your account manager prior to campaign promotion. Also in case of fraud, bot, mixed traffic, low quality traffic or any kind of fraudulent activity is found the payment might be deducted in full for your source. **all your traffic is monitored with anti-fraud system 24metrics (Fraudshield)(payouts: IN=0.66) - Non incent";
      //  System.out.println(a.substring(0,3500));
    }

    /**
     * 1 Require Approval 需要批准
     * 2 Public 公共
     * 3 Private 个人
     */
    public String transApproval(int offerApproval) {

        if (offerApproval == 1) {
            return "Need Approval";
        } else if (offerApproval == 2) {
            return "Public";
        } else if (offerApproval == 3) {
            return "Private";
        }
        return "";
    }


    public static void drviceRules(String json, Map<String, String> params) {
        JSONObject jsonObject = JSON.parseObject(json);
        JSONArray targetArray = jsonObject.getJSONArray("target");

        int i = 0;
        for (Object obj : targetArray) {
            JSONObject jsonObject2 = (JSONObject) obj;
            OfferPlatformEntity offerPlatformEntity = JSONObject.parseObject(jsonObject2.toJSONString(), OfferPlatformEntity.class);
            String drviceRules = "";
            if (offerPlatformEntity.getIsAbove() == 0) {
                drviceRules = offerPlatformEntity.getSystem() + "";
            } else {
                drviceRules = offerPlatformEntity.getSystem() + "(" + offerPlatformEntity.getAboveVersion() + "-)";
            }
            params.put("device_rules[" + i + "]", "1:OS:" + drviceRules);
            ++i;
        }
    }

    public static void countryRules(String json, Map<String, String> params) {
        OfferGeoDTO offerGeoDTO = JSON.parseObject(json, OfferGeoDTO.class);
        List<OfferGeoDTO.TargetBean> targetList = offerGeoDTO.getTarget();
        int i = 0;
        for (OfferGeoDTO.TargetBean targetBean : targetList) {
            if ("UK".equals(targetBean.getCountry_code())) {
                params.put("geo_countries[" + i + "]", "GB");
            } else {
                params.put("geo_countries[" + i + "]", targetBean.getCountry_code());
            }

            ++i;
        }
    }


}

